package com.ayf.payment.game.api.controller.paychannel;

import com.alibaba.fastjson.JSONObject;
import com.ayf.payment.game.api.channel.jiabei.util.JbStringUtil;
import com.ayf.payment.game.api.dto.platform.PaymentChannelDTO;
import com.ayf.payment.game.api.entity.Order;
import com.ayf.payment.game.api.service.payment.faka.util.FaKaSignUtil;
import com.ayf.payment.game.api.type.OrderStatus;
import com.ayf.payment.game.api.utils.JsonUtils;
import com.ayf.payment.game.api.utils.SnowFlakeUtils;
import com.ayf.payment.game.api.wx.WxSendMsgUtils;
import com.swwx.charm.commons.lang.utils.LogPortal;
import com.swwx.charm.zookeeper.exception.GetLockFailedException;
import com.swwx.charm.zookeeper.exception.ReleaseLockFailedException;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
import java.util.TreeMap;

@RequestMapping("/v/sky98/pay")
@RestController
public class Sky98PayNotifyController extends BasePayNotifyController {

	@Autowired
	private WxSendMsgUtils wxSendMsgUtils;

	@RequestMapping("/notify")
	public void notify(HttpServletRequest request, HttpServletResponse response, @RequestBody JSONObject reqParam) {
		PrintWriter pw = null;
		String traceId = SnowFlakeUtils.getTraceId();
		try {
			LogPortal.info("{} 捷付通交易异步通知 参数:{}", traceId, reqParam);
			String orderId = reqParam.getString("requestId");
			if (StringUtils.isEmpty(orderId)) {
				LogPortal.info("{} 捷付通交易推送过来到商户订单号数值为空，不进行后续操作", traceId);
				pw.write("SUCCESS");
				pw.flush();
				return;
			}
			super.notifyAsync(request, response, orderId, reqParam);
		} catch (Exception e) {
			LogPortal.error("{} 捷付通交易异步通知验签业务逻辑处理失败，具体原因:{}", e, traceId, e.getMessage());
			pw.write("异步通知响应验签处理失败：" + e.getMessage());
			pw.flush();
		} finally {
			if (pw != null)
				pw.close();
		}
	}

	/**
	 * 代付异步通知处理
	 */
	@RequestMapping("/paynotify")
	public void payNotify(HttpServletRequest request, HttpServletResponse response, @RequestBody JSONObject reqParam) {
		PrintWriter pw = null;
		String traceId = SnowFlakeUtils.getTraceId();
		try {
			LogPortal.info("{} 捷付通代付交易异步通知 参数:{}", traceId, reqParam);
			String orderId = reqParam.getString("requestId");
			if (StringUtils.isEmpty(orderId)) {
				LogPortal.info("{} 捷付通代付推送过来到商户订单号数值为空，不进行后续操作", traceId);
				pw.write("SUCCESS");
				pw.flush();
				return;
			}
			super.agentPayNotifyAsync(request, response, orderId, reqParam);
		} catch (Exception e) {
			LogPortal.error("{} 捷付通代付异步通知验签业务逻辑处理失败，具体原因:{}", e, traceId, e.getMessage());
			pw.write("代付异步通知响应验签处理失败：" + e.getMessage());
			pw.flush();
		} finally {
			if (pw != null)
				pw.close();
		}
	}

	@RequestMapping("/returns")
	public void returns(HttpServletRequest request, HttpServletResponse response) {
		String orderno = JbStringUtil.formatString(request.getParameter("out_trade_no"));
		super.notifySync(request, response, orderno);
	}

	@Override
	protected void notifyAsyncBusinesExec(HttpServletRequest request, HttpServletResponse response, Object obj) {
		PrintWriter pw = null;
		String traceId = SnowFlakeUtils.getTraceId();
		String orderno;
		String resCode = "SUCCESS";
		try {
			pw = response.getWriter();
			JSONObject dataJson = (JSONObject) obj;
			orderno = dataJson.getString("requestId");
			if (StringUtils.isEmpty(orderno)) {
				LogPortal.info("{} 捷付通交易异步通知 订单号数值为空，不进行后续操作", traceId);
				return;
			}
			Order order = orderService.selectByMerchantOrderNo(orderno);
			if (order == null) {
				LogPortal.error("{} 捷付通交易异步通知 订单号[{}]在我方系统查询不到", traceId, orderno);
				return;
			}
			PaymentChannelDTO paymentChannelDTO = systemInitialization.channelDTO(order.getPayChannleId());
			String KeyValue = paymentChannelDTO.getChannelKey();

			TreeMap<String, String> paramMap = JsonUtils.fromJson(dataJson.toJSONString(), TreeMap.class);
			String signVer = FaKaSignUtil.getSign(traceId, "捷付通交易异步通知", paramMap, KeyValue);

			// 支付结果，成功SUCCESS失败FAIL
			String status = dataJson.getString("status");
			OrderStatus orderStatus = OrderStatus.PROCESSING;
			if (dataJson.getString("code").equalsIgnoreCase(signVer.trim())) {
				String errMsg = "渠道异步通知返回失败";
				if ("SUCCESS".equals(status)) {
					orderStatus = OrderStatus.SUCCESS;
				}
				else if ("FAIL".equals(status)) {
					orderStatus = OrderStatus.FAIL;
				}
				if (OrderStatus.PROCESSING.equals(order.getOrderStatus())) {
					String XY_GAME_PAY_LOCK_FLAG = System.getenv("XY_GAME_PAY_LOCK_FLAG");
					String orderLockName = "orderLock".concat(getClass().getSimpleName()).concat(XY_GAME_PAY_LOCK_FLAG).concat(orderno);
					boolean orderLock = false;
					try {
						if (orderLock = distributedLock.getLock(orderLockName)) {
							Order order2 = orderService.selectByMerchantOrderNo(orderno);
							if (order2 != null && OrderStatus.PROCESSING.equals(order2.getOrderStatus())) {
								order.setOrderStatus(orderStatus);
								order.setOrderNo(dataJson.getString("orderId"));
								JSONObject dataObject = new JSONObject();
								if (OrderStatus.FAIL.equals(order.getOrderStatus())) {
									dataObject.put("err_code", status);
									dataObject.put("err_code_desc", errMsg);
								}
								orderService.paymentOrder(order, dataObject);
								if (OrderStatus.SUCCESS.equals(order.getOrderStatus())) {
									orderService.orderToGetWay(order);
									try {
										wxSendMsgUtils.rechargeSuccess(order);
									} catch (Exception e) {
										LogPortal.error("{} 捷付通交易异步通知 商户订单号[{}]CallBack 微信通知异常", e, traceId, orderno);
									}
								}
							}
						}
					} catch (GetLockFailedException e) {
						LogPortal.error("{} >>> [DISTRIBUTED_LOCK_ACQUIRE_FAILED_ZK] 分布式锁获取失败,锁名称为:{}", orderno, orderLockName);
						LogPortal.error("{} >>> {} 获取lock失败", e, orderno, orderLockName);
					} catch (Exception e) {
						LogPortal.error("{} >>> {} 任务执行出错 ", e, orderno, orderLockName);
					} finally {
						if (orderLock) {
							LogPortal.info(orderno + " >>> " + orderLockName + " finished.");
							try {
								distributedLock.releaseLock(orderLockName);
							} catch (ReleaseLockFailedException e) {
								LogPortal.error("{} >>> [DISTRIBUTED_LOCK_RELEASE_FAILED_ZK] 分布式锁释放失败,锁名称为:{}", orderno, orderLockName);
								LogPortal.error("{} >>> {} 释放失败", e, orderno, orderLockName);
							}
						}
					}
				}
				else {
					LogPortal.info("{} 捷付通交易异步通知 商户订单号[{}] 异步通知 不在更新订单状态：[{}]", traceId, orderno, order.getOrderStatus());
				}
			}
			else {
				LogPortal.error("{} 捷付通交易异步通知 商户订单号[{}] 异步通知验签失败", traceId, orderno);
			}
		} catch (Exception e) {
			LogPortal.error("{} 捷付通交易异步通知 验签业务逻辑处理失败，具体原因:{}", e, traceId, e.getMessage());
		} finally {
			pw.write(resCode);
			pw.flush();
			if (pw != null)
				pw.close();
		}
	}

	@Override
	protected void notifySyncBusinesExec(HttpServletRequest request, HttpServletResponse response) {
	}

	@Override
	protected void agentPayNotifyAsyncBusinesExec(HttpServletRequest request, HttpServletResponse response, Object obj) {
		String traceId = SnowFlakeUtils.getTraceId();
		PrintWriter pw = null;
		try {
			pw = response.getWriter();
			JSONObject dataJson = (JSONObject) obj;
			TreeMap<String, String> reqParmMap = JsonUtils.fromJson(dataJson.toJSONString(), TreeMap.class);
			String orderno = dataJson.getString("requestId");
			if (StringUtils.isEmpty(orderno)) {
				LogPortal.info("{} 捷付通代付异步通知 商户订单号数值为空，不进行后续操作", traceId);
				return;
			}
			if (orderno.startsWith("Y")) {
				merchantCashOutService.sky98PaymentOnBehalfOf(traceId, reqParmMap);
			}
			else {
				merchantPayOrderService.sky98PayNotify(traceId, reqParmMap);
			}
			pw.write("SUCCESS");
			pw.flush();
		} catch (Exception e) {
			LogPortal.error("{} 捷付通代付异步通知 业务逻辑处理失败，具体原因:{}", e, traceId, e.getMessage());
			pw.write("捷付通代付异步通知 业务逻辑处理失败：" + e.getMessage());
			pw.flush();
		} finally {
			if (pw != null)
				pw.close();
		}
	}

}
